package com.example.dingtalk.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.dingtalk.entity.dto.ExcelDto;
import com.example.dingtalk.entity.po.DingoaManagementProcess;
import com.example.dingtalk.mapper.DingoaManagementProcessMapper;
import com.example.dingtalk.service.ExpenseProcessHandler;
import com.example.dingtalk.service.IDingoaManagementProcessService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dingtalk.util.TextConstants;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 * 管理费用审批流程表 服务实现类
 * </p>
 *
 * @author ckcool
 * @since 2024-08-08
 */
@Service
public class DingoaManagementProcessServiceImpl extends ServiceImpl<DingoaManagementProcessMapper, DingoaManagementProcess> implements IDingoaManagementProcessService, ExpenseProcessHandler {
    /**
     * 处理数据保存
     *
     * @param instance
     * @param flag
     */
    @Override
    public void handle(GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult instance, Boolean flag, String instanceId) throws ParseException {
        DingoaManagementProcess managementExpenseprocess = new DingoaManagementProcess();
        String title = instance.getTitle();
        managementExpenseprocess.setTitle(title);
        //实例id
        managementExpenseprocess.setInstanceId(instanceId);
        managementExpenseprocess.setApplicantDepartment(instance.getOriginatorDeptName());
        managementExpenseprocess.setVoucherColumn(instance.getBusinessId());
        if ("COMPLETED".equals(instance.getStatus())) {
            managementExpenseprocess.setIsComplete("已完成");
        } else {
            managementExpenseprocess.setIsComplete("待审批");
        }

        List<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues> componentValues = instance.getFormComponentValues();
        for (GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues componentValue : componentValues) {
            switch (componentValue.getName()) {
                case "付款事由":
                    managementExpenseprocess.setSummary(componentValue.getValue());
                    break;
                case "项目":
                    managementExpenseprocess.setProject(componentValue.getValue());
                    break;
                case "收款单位（个人）":
                    managementExpenseprocess.setRecipientName(componentValue.getValue());
                    break;
                case "收款人身份证号":
                    managementExpenseprocess.setRecipientIdNumber(componentValue.getValue());
                    break;
                case "收款单位（个人）账号":
                    managementExpenseprocess.setRecipientAccountNumber(componentValue.getValue());
                    break;
                case "收款单位（个人）开户行网点":
                    managementExpenseprocess.setReceivingBank(componentValue.getValue());
                    break;
                case "付款金额（元）":
                case "付款金额":
                    managementExpenseprocess.setCredit(new BigDecimal(componentValue.getValue()));
                    break;
                case "店铺号":
                    managementExpenseprocess.setStoreNumber(componentValue.getValue());
                    break;
                case "币种":
                case "币别":
                    // 获取原始的字符串值
                    String originalValue = componentValue.getValue();
                    String cleanedValue = originalValue.replace("[", "").replace("]", "").replace("\"", "");
                    managementExpenseprocess.setCurrency(cleanedValue);
                    break;
                case "费用类别":
                    // 获取费用类别
                    String expenseCategory = componentValue.getValue();
                    if (expenseCategory != null && !expenseCategory.isEmpty()) {
                        String correspondingFieldName = getCorrespondingFieldName(expenseCategory);
                        if (correspondingFieldName != null) {
                            for (GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues subComponentValue : componentValues) {
                                if (subComponentValue.getName().equals(correspondingFieldName)) {
                                    managementExpenseprocess.setAttributionDetails(subComponentValue.getValue());
                                    break;
                                }
                            }
                        }
                    }
                    break;
                case "付款公司":
                    if ("其他".equals(componentValue.getValue())) {
                        managementExpenseprocess.setPaymentBank("苏发国际");
                    } else {
                        managementExpenseprocess.setPaymentBank(componentValue.getValue());
                    }
                    break;
                default:
                    break;
            }
        }
        //截取title
        managementExpenseprocess.setDebitSubject("管理费用");
        managementExpenseprocess.setApplicant(extractApplicantFromTitle(title));
        //拉取时间
        managementExpenseprocess.setFetchDate(new Date());

        String createTimeString = instance.getCreateTime();
        LocalDateTime localDateTime = LocalDateTime.parse(createTimeString, DateTimeFormatter.ISO_DATE_TIME);
        Date createTime = Date.from(localDateTime.atZone(ZoneId.of("Asia/Shanghai")).toInstant());

        //创建时间
        managementExpenseprocess.setCreateTime(createTime);

        String finishTimeString = instance.getFinishTime();
        if (finishTimeString != null) {
            LocalDateTime localDate = LocalDateTime.parse(finishTimeString, DateTimeFormatter.ISO_DATE_TIME);
            Date finishTime = Date.from(localDate.atZone(ZoneId.of("Asia/Shanghai")).toInstant());
            //完成时间
            managementExpenseprocess.setFinishTime(finishTime);
        }


        //更新时间
        managementExpenseprocess.setUpdateTime(new Date());
        //System.out.println(managementExpenseprocess);
        // 存储到相应的表
        this.save(managementExpenseprocess);
    }

    /**
     * 返回费用类别
     *
     * @param expenseCategory
     * @return
     */
    private String getCorrespondingFieldName(String expenseCategory) {
        switch (expenseCategory) {
            case "行政类":
                return "行政费用";
            case "工资类":
                return "工资费用";
            case "管理类":
                return "管理费用";
            case "人事类":
                return "人事费用";
            case "财务类":
                return "财务费用";
            case "销售类":
                return "销售费用";
            case "税费类":
                return "税费费用";
            default:
                return null;
        }
    }

    /**
     * 根据标题提取申请人
     *
     * @param title
     * @return
     */
    private String extractApplicantFromTitle(String title) {
        Pattern pattern = Pattern.compile(TextConstants.PATTERN);
        Matcher matcher = pattern.matcher(title);
        if (matcher.find()) {
            return matcher.group(1);
        } else {
            throw new IllegalArgumentException("Cannot extract applicant from title: " + title);
        }
    }


    @Override
    public List<ExcelDto> toExcelDto(String startDate, String endDate, Boolean flag) {

        List<DingoaManagementProcess> expenseprocesses = null;
        // 构建基础查询
        LambdaQueryWrapper<DingoaManagementProcess> query = new LambdaQueryWrapper<DingoaManagementProcess>()
                .eq(DingoaManagementProcess::getIsComplete, "待审批")
                .ge(DingoaManagementProcess::getCreateTime, startDate)
                .le(DingoaManagementProcess::getCreateTime, endDate);
        if (!flag) {
            query.eq(DingoaManagementProcess::getIsExporter, false);
        }
        expenseprocesses = this.list(query);

        // 转换为 ExcelDto 列表
        List<ExcelDto> excelDtos = new ArrayList<>();
        for (DingoaManagementProcess managementExpenseprocess : expenseprocesses) {
            ExcelDto excelDto = BeanUtil.copyProperties(managementExpenseprocess, ExcelDto.class);
            excelDto.setJournalProject(managementExpenseprocess.getDebitSubject());
            excelDto.setPaymentCompany(managementExpenseprocess.getPaymentBank());
            excelDto.setAccountingDepartment(managementExpenseprocess.getApplicantDepartment());
            BigDecimal credit = managementExpenseprocess.getCredit();
            excelDto.setCredit(credit);
            managementExpenseprocess.setIsExporter(true);
            excelDtos.add(excelDto);
        }
        updateBatchById(expenseprocesses);
        return excelDtos;
    }

    @Override
    public List<ExcelDto> toExcel(String startDate, String endDate, Boolean flag) {
        // 查询在指定日期范围内的数据并转换为 ExcelDto 列表
        // 假设 list() 方法会返回所有的 AccountsPayableprocess 对象
        List<DingoaManagementProcess> expenseprocesses = null;
        LambdaQueryWrapper<DingoaManagementProcess> query = new LambdaQueryWrapper<>();
        query.eq(DingoaManagementProcess::getIsComplete, "已完成");
        query.ge(DingoaManagementProcess::getCreateTime, startDate);
        query.le(DingoaManagementProcess::getCreateTime, endDate);
        if (!flag) {
            query.eq(DingoaManagementProcess::getIsExporter, false);
        }
        expenseprocesses = this.list(query);


        List<ExcelDto> excelDtos = new ArrayList<>();
        for (DingoaManagementProcess expenseprocess : expenseprocesses) {
            ExcelDto excelDto = BeanUtil.copyProperties(expenseprocess, ExcelDto.class);
            excelDto.setJournalProject(expenseprocess.getDebitSubject());
            excelDto.setPaymentCompany(expenseprocess.getPaymentBank());
            excelDto.setAccountingDepartment(expenseprocess.getApplicantDepartment());
            excelDto.setAttributionDetails(expenseprocess.getStoreNumber());
            BigDecimal credit = expenseprocess.getCredit();
            excelDto.setCredit(credit);
            expenseprocess.setIsExporter(true);
            excelDtos.add(excelDto);
        }
        updateBatchById(expenseprocesses);
        return excelDtos;
    }
}
